package c2.cross.business.guildwar;

import c2.advanced.business.base.KvData;
import c2.cross.business.CrossBody;
import c2.cross.business.base.CrossModule;
import c2.cross.business.base.CrossSubModule;
import c2.cross.business.guildwar.common.GuildWarStatus;
import c2.cross.business.guildwar.core.GWCrossMessagingModule;
import c2.cross.business.guildwar.core.GWCrossReceiveModule;
import c2.cross.business.guildwar.rank.GuildWarGuildRankModule;
import c2.cross.business.guildwar.rank.GuildWarRoleRankModule;
import cate.common.game.mail.MailCmd;
import cate.common.table.d.GDGuildWar;
import cate.common.table.d.GDMail;
import cate.common.table.d.GDOperation;
import cate.common.util.TimeTool;
import cate.common.util.XT;
import cate.game.pvp.guildwar.data.base.GWMatchGroup;
import cate.game.pvp.guildwar.data.msg.GWChampionInnerResp;
import cate.game.pvp.guildwar.data.msg.GWGuildRankRecordInnerReq;
import cate.game.pvp.guildwar.data.msg.GWRoleRankRecordInnerReq;
import cate.game.pvp.guildwar.data.msg.GWSignInnerReq;
import cate.game.pvp.guildwar.data.rank.GWChampion;
import cate.game.pvp.guildwar.data.rank.GWGuildRank;
import cate.game.pvp.guildwar.data.rank.GWRoleRank;
import cate.game.util.IntervalCounter;
import easy.java.dev.note.NoteClass;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

@NoteClass("跨服公会战模块")
@Slf4j
public class GuildWarModule extends CrossModule<GuildWarStatus> {

	public GuildWarModule(CrossBody context) {
		super(context);
	}

	public GWCrossMessagingModule message = new GWCrossMessagingModule();
	public GWCrossReceiveModule receive = new GWCrossReceiveModule();

	public GuildWarGuildRankModule guildRank = new GuildWarGuildRankModule();
	public GuildWarRoleRankModule roleRank = new GuildWarRoleRankModule();

	private IntervalCounter saveTrigger = new IntervalCounter(3600);
	private IntervalCounter minTrigger = new IntervalCounter(60);

	@Override
	protected CrossSubModule[] getSubModules() {
		return new CrossSubModule[]{message, receive, guildRank, roleRank};
	}

	@Override
	protected String getStatusKey() {
		return KvData.KEY_GUILD_WAR;
	}

	@Override
	protected Class<GuildWarStatus> getStatusClass() {
		return GuildWarStatus.class;
	}

	@Override
	public String getName() {
		return "公会战";
	}

	@Override
	public void initDependent() throws Exception {
		super.initDependent();
		checkDaySpan();
		checkStart();
		noticeBase(true, true);
	}

	@Override
	protected int getIntervalSeconds() {
		return 1;
	}

	@Override
	protected void onInterval() throws Exception {
		if (System.currentTimeMillis() > status.base.endTime) {
			onSeasonOver();
		}
		boolean change = status.timeTable.tick();
		if (change) {
			onPeriodChange();
		}
		if (minTrigger.trigger()) {
			if (status.timeTable.period == GDGuildWar.Period.MATCH) {
				noticeBase(true, false);
			}
			if (status.timeTable.period == GDGuildWar.Period.SETTLE_RWD) {
				noticeBase(false, true);
			}
		}
		if (saveTrigger.trigger()) {
			saveAll();
		}
	}

	private void saveAll(){
		saveStatus();
		roleRank.save();
		guildRank.save();
	}

	private void onPeriodChange(){
		if (status.timeTable.period == GDGuildWar.Period.MATCH) {
			status.match.buildMatchList();
			noticeBase(true,false);
		}
	}

	private void checkDaySpan(){
		if(TimeTool.isSameDay(status.lastDaySpanTime,System.currentTimeMillis())){
			return;
		}
		onDaySpan();
	}

	public void onDaySpan(){
		log.info("[公会战]开始跨天");
		status.onDaySpan();
		checkStart();
	}

	private void onSeasonOver() {
		log.info("[公会战]一个赛季结束了");
		//本期轮空
		List<GWGuildRank> guildRanks = guildRank.getCopyList();
		if(XT.isBlank(guildRanks)){
			log.info("[公会战]本期轮空");
		} else {
			//记录冠军 发段位奖励
			GWGuildRank topGuild = guildRanks.get(0);
			log.info("[公会战]本期最强公会是[{}]", topGuild.profile.name);
			status.setChampion(topGuild);
			//发最强公会奖励
			message.settleGuildRwd(topGuild.profile.srvId, topGuild.profile.uid);

			if (XT.isNotBlank(roleRank.getList())) {
				GWRoleRank topRole = roleRank.getList().get(0);
				//最强玩家
				MailCmd mailCmd = new MailCmd().withOpr(GDOperation.GUILD_WAR_TOP_ROLE, status.base.index)
						.withContent(GDMail.Tid.TOP_GUILD_ROLE_RWD, new ArrayList<>())
						.withReward(GDGuildWar.TOP_ROLE_SEASON_RWD_STR);
				mailCmd.addRole(topRole.owner.uid).withSrvId(topRole.owner.base.srvId);
				context.common.sendMail(mailCmd);

				log.info("[公会战]本期最强玩家是[{}服]的[{}]", topRole.owner.base.srvId, topRole.owner.base.name);
			}
			status.base.index++;
			log.info("[公会战]进入第{}赛季", status.base.index);
		}
		status.base.setStartTime(TimeTool.getZeroTimeStamp(System.currentTimeMillis()));
		guildRank.clearList();
		roleRank.clearList();
		status.base.print();
		noticeBase(false,false);
	}

	private void checkStart() {
		boolean start = status.timeTable.checkStart(context.table.guildWar.time);
		if(start){
			log.info("跨服开启了一场[公会战]");
			onPeriodChange();
		}
	}

	public void onGameConnect(int srvId) {
		message.sendBackBase(srvId, status,guildRank.getCopyList());
	}

	public boolean handleSign(GWSignInnerReq req) {
		if(status.timeTable.period!=GDGuildWar.Period.SIGN_UP){
			return false;
		}
		status.handleSign(req.srvId, req.list);
		return true;
	}

	public void handleRecordRole(GWRoleRankRecordInnerReq req){
		roleRank.record(req.owner,req.value);
	}

	public void handleRecordGuild(GWGuildRankRecordInnerReq req) {
		log.info("接收到[{}]服[{}]公会的公会战数据同步 积分为[{}]", req.profile.srvId, req.profile.name, req.value);
		guildRank.record(req.profile, req.value);
	}

	public GWChampionInnerResp getChampion(){
		return GWChampionInnerResp.of(status.champions);
	}

	public void admire(int season) {
		GWChampion champion = status.champions.get(season);
		if (champion != null) {
			champion.admire++;
		} else {
			log.error("游戏服尝试给第[{}]赛季的冠军点赞 但是冠军不存在", season);
		}
	}

	/**
	 * 同步基础数据
	 * @param needMatch 是否需要匹配数据
	 * @param needRank 是否需要公会排名数据
	 */
	private void noticeBase(boolean needMatch, boolean needRank) {
		List<GWMatchGroup> matchList = needMatch ? status.match.matchList : null;
		List<GWGuildRank> rankList = needRank ? guildRank.getCopyList() : null;
		message.noticeBase(status.base, matchList, rankList);
	}
}
